package com.xiaocq.wordskiller;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.TreeSet;

import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.view.View;
import android.view.View.OnClickListener;

import com.xiaocq.wordskiller.db.DatabaseHelper;
import com.xiaocq.wordskiller.db.VocabularyDatabase.VocabularyMeta;
import com.xiaocq.wordskiller.fileIO.WordsReaderORWriter;

public class ActivityHelper {
	private Context context;
	
	private DatabaseHelper mOpenHelper;

	private static final String[] COLUMNS = new String[] { VocabularyMeta._ID,
			VocabularyMeta.VOCABULARY, VocabularyMeta.EXPLAIN };

	private SQLiteDatabase db;

	public ActivityHelper(Context context) {
		this.context = context;
	}
	
	public void open() {
		mOpenHelper = new DatabaseHelper(context);
		db = mOpenHelper.getReadableDatabase();
	}

	public void close() {
		db.close();
		mOpenHelper.close();
	}

	public Cursor getCursorDataByUnitId(int unitId) {
		String selection = VocabularyMeta.BELONG_TO + " = " + unitId;
		Cursor cursor = db.query(VocabularyMeta.TABLE_NAME, COLUMNS, selection,
				null, null, null, null);

		return cursor;
	}


	public Cursor getCursorDataByType(int testType) {
		Cursor cursor;
		switch (testType) {
		case 1:
			cursor = db.query(VocabularyMeta.TABLE_NAME, COLUMNS,
					VocabularyMeta.ANSWER_STATE + " = 0", null, null, null,
					null);
			break;
		case 2:
			cursor = db.query(VocabularyMeta.TABLE_NAME, COLUMNS,
					VocabularyMeta.ANSWER_STATE + " != 0", null, null, null,
					null);
			break;
		case 3:
			cursor = db.query(VocabularyMeta.TABLE_NAME, COLUMNS,
					VocabularyMeta.ANSWER_STATE + " = 1", null, null, null,
					null);
			break;
		case 4:
			cursor = db.query(VocabularyMeta.TABLE_NAME, COLUMNS,
					VocabularyMeta.ANSWER_STATE + " = 2", null, null, null,
					null);
			break;
		default:
			cursor = db.query(VocabularyMeta.TABLE_NAME, COLUMNS, null, null,
					null, null, null);
		}

		return cursor;
	}
	
	public Cursor getUnitWrongData(int unitId) {
		String selection = VocabularyMeta.BELONG_TO + " = " + unitId + " AND "
				+ VocabularyMeta.ANSWER_STATE + " = 2";
		Cursor cursor = db.query(VocabularyMeta.TABLE_NAME, COLUMNS, selection,
				null, null, null, null);

		return cursor;
	}

	public Cursor getUnitWrongSetData() {
		Cursor cursor;
		String sql = "SELECT " + VocabularyMeta.BELONG_TO + ",count(*) FROM "
				+ VocabularyMeta.TABLE_NAME + " WHERE "
				+ VocabularyMeta.ANSWER_STATE + " = 2 GROUP BY "
				+ VocabularyMeta.BELONG_TO;
		cursor = db.rawQuery(sql, null);
		return cursor;
	}

	public Cursor getCursorDataOfWrongWords(long currentTimeInMillis) {
		String sql = VocabularyMeta.ANSWER_STATE + " = 2 AND "
				+ VocabularyMeta.LEAST_ACCESS + " = " + currentTimeInMillis;
		Cursor cursor = db.query(VocabularyMeta.TABLE_NAME, COLUMNS, sql, null,
				null, null, null);
		return cursor;
	}


	public TreeSet<Integer> getCheckedSet(int[] details, int length) {
		int cursorId = 0;
		TreeSet<Integer> result = new TreeSet<Integer>();
		for (int i = 0; i < length; i++) {
			cursorId = details[i] % 10000;
			result.add(cursorId);
		}
		return result;
	}

	public int[] getDetailsFromFile(boolean isUnitTest, int mTestCount) {
		WordsReaderORWriter wordsROW = new WordsReaderORWriter(context);
		FileInputStream inputStream;
		if (isUnitTest) {
			inputStream = getInputStreamFromInternalFile(CommandList.UNIT_FILE_NAME);
		} else {
			inputStream = getInputStreamFromInternalFile(CommandList.COSTUM_FILE_NAME);
		}
		return wordsROW.getDetailOfTest(inputStream, mTestCount);
	}

	private FileInputStream getInputStreamFromInternalFile(String fileName) {
		try {
			return context.openFileInput(fileName);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public boolean saveIntoFile(int[] details, boolean isUnitTest) {
		WordsReaderORWriter wordROW = new WordsReaderORWriter(context);
		FileOutputStream outputStream = getOutputStream(isUnitTest);

		return wordROW.writeIntoInternalFile(outputStream, details);
	}

	private FileOutputStream getOutputStream(boolean isUnitTest) {
		try {
			return context.openFileOutput(
					isUnitTest ? CommandList.UNIT_FILE_NAME
							: CommandList.COSTUM_FILE_NAME,
					Context.MODE_PRIVATE);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public void saveUnitTestParam(SharedPreferences.Editor editor,
			boolean notUnit, int unitId, int finishedCount, long allTimeInMillis) {
		editor.putBoolean(CommandList.IS_THE_NEW_TEST, false);
		editor.putBoolean(CommandList.UNIT_TEST_MODEL, notUnit);
		editor.putInt(CommandList.UNIT_ID, unitId);
		editor.putInt(CommandList.UNIT_FINISHED_COUNTS, finishedCount);
		editor.putLong(CommandList.UNIT_TIME_COST, allTimeInMillis);
		editor.commit();
	}

	public void saveOptionalTestParam(SharedPreferences.Editor editor,
			boolean notUnit, int testCount, int finishedCount, int testType,
			long allTimeInMillis) {
		editor.putBoolean(CommandList.IS_THE_NEW_TEST, false);
		editor.putBoolean(CommandList.COSTUM_TEST_MODEL, notUnit);
		editor.putInt(CommandList.COSTUM_TEST_COUNTS, testCount);
		editor.putInt(CommandList.COSTUM_FINISHED_COUNTS, finishedCount);
		editor.putInt(CommandList.COSTUM_TEST_TYPE, testType);
		editor.putLong(CommandList.COSTUM_TIME_COST, allTimeInMillis);
		editor.commit();
	}

	public int getWrappedId(int number, boolean isCorrect) {
		int rest = number % 10000;
		int num = number / 10000;
		num = num / 10 * 10 + (isCorrect ? 1 : 2);
		num = num * 10000 + rest;
		return num;
	}

	public int updateResult(int[] details, long currentTime) {

		String sql = "UPDATE " + VocabularyMeta.TABLE_NAME + " SET "
				+ VocabularyMeta.ANSWER_STATE + " = ?, "
				+ VocabularyMeta.LEAST_ACCESS + " = ? WHERE "
				+ VocabularyMeta._ID + " = ?";
		Object[] objects = new Object[3];
		objects[1] = currentTime;
		int length = details.length;
		int isCorrect;
		int rowId;
		int partOfId;
		int wrong = 0;
		open();
		try {
			db.beginTransaction();
			for (int i = 0; i < length; i++) {
				partOfId = details[i] / 10000;
				rowId = partOfId / 10;
				isCorrect = partOfId % 10;
				if (isCorrect == 2)
					wrong++;
				objects[0] = isCorrect;
				objects[2] = rowId;

				db.execSQL(sql, objects);
			}
			db.setTransactionSuccessful();
		} catch (SQLException e) {
			e.printStackTrace();
			return 0;
		} finally {
			db.endTransaction();
			close();
		}
		return wrong;
	}

	public void clearUnitParams(SharedPreferences.Editor editor,
			boolean testModel) {
		editor.putBoolean(CommandList.IS_THE_NEW_TEST, true);
		editor.putBoolean(CommandList.UNIT_TEST_MODEL, testModel);
		editor.putInt(CommandList.UNIT_ID, -1);
		editor.putInt(CommandList.UNIT_FINISHED_COUNTS, 0);
		editor.putLong(CommandList.UNIT_TIME_COST, 0L);
		editor.commit();
	}

	public void clearOptionalParam(SharedPreferences.Editor editor,
			boolean testModel) {
		editor.putBoolean(CommandList.IS_THE_NEW_TEST, true);
		editor.putBoolean(CommandList.COSTUM_TEST_MODEL, testModel);
		editor.putInt(CommandList.COSTUM_TEST_COUNTS, 30);
		editor.putInt(CommandList.COSTUM_FINISHED_COUNTS, 0);
		editor.putInt(CommandList.COSTUM_TEST_TYPE, -1);
		editor.putLong(CommandList.COSTUM_TIME_COST, 0L);
		editor.commit();
	}
}
